#include "midef.h"

#include <malloc.h>
#include <string.h>

void ReleaseList (MIList * list);
void ReleaseValue (MIValue * value);
void ReleaseResult (MIResult * result);

void ReleaseMIOutput (MIGDBOutput * output)
{
    MIOutOfBandRecord * pOutOfBandRecord = output->m_pOutOfBandRecord;
    while (pOutOfBandRecord) {
        if (pOutOfBandRecord->m_type == ASYNC) {
            ReleaseResult(pOutOfBandRecord->m_pAsyncRecord->m_pResult);
        } else { // STREAM
            free(pOutOfBandRecord->m_pStreamRecord->m_string);
        }

        MIOutOfBandRecord * next = pOutOfBandRecord->m_pNext;
        delete pOutOfBandRecord;
        pOutOfBandRecord = next;
    }

    ReleaseMIResultRecord (output->m_pResultRecord);

    delete output;
}

void ReleaseMIResultRecord (MIResultRecord * record)
{
    if (record) {
        ReleaseResult (record->m_pResult);
        delete record;
    }
}

void ReleaseList (MIList * list)
{
    if (! list)
        return;

    if (list->m_type == VALUE)
        free (list->m_pValue);
    else if (list->m_type == RESULT)
        ReleaseResult (list->m_pResult);

    delete list;
}

void ReleaseValue (MIValue * value)
{
    while (value) {
        if (value->m_type == VT_CONST)
            free(value->m_string);
        else if (value->m_type == VT_TUPLE)
            ReleaseResult(value->m_pResult);
        else // value->m_type == LIST
            ReleaseList(value->m_pList);

        MIValue *next = value->m_pNext;
        delete value;
        value = next;
    }
}

void ReleaseResult (MIResult * result)
{
    while (result) {
        free (result->m_variable);
        ReleaseValue (result->m_pValue);

        MIResult * next = result->m_pNext;
        delete result;
        result = next;
    }
}

MIValue * GetMIValue (MIResult * result, MIString variable)
{
    while (result) {
        if (strcmp (result->m_variable, variable) == 0)
            return result->m_pValue;
        result = result->m_pNext;
    }
    return 0;
}

MIString ConvertCString (MICString cstr)
{
    if (! cstr)
        return 0;

    char c;
    char * p, * q;

    for (p = q = cstr; c = * q; ++ q, ++ p) {
        if (c == '\\') {
            c = * (++ q);
            if (c == 'n')
                c = '\n';
        }

        if (p != q)
            * p = c;
    }

    *p = 0;

    return cstr;
}
